package com.neusoft.databus.sap.trap;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import javax.annotation.PostConstruct;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import com.neusoft.bizcore.common.cache.CacheService;
import com.neusoft.bizcore.web.dto.result.ResultDTO;
import com.neusoft.bizcore.web.utils.JsonUtils;
import com.neusoft.databus.agent.service.AssociateResourceService;
import com.neusoft.databus.common.constant.DatabusConstant;
import com.neusoft.databus.common.dto.ResourceDTO;

import lombok.extern.slf4j.Slf4j;

/**
 * SNMP告警处理
 *
 * @author sunchf
 * @date 2019年3月28日 上午8:52:49
 */
@Slf4j
@Service
public class SnmptrapService implements SnmptrapProcessor {

    @Autowired
    private AssociateResourceService associateResourceService;
    @Autowired
    private CacheService cacheService;
    private ExecutorService executorService;
    @Autowired
    StringRedisTemplate template;
    @Value("${databus.alarm.redis.subscribeChannel: channel:alarm}")
    private String redisSubscribeChannel;

    @PostConstruct
    public void init() {
        this.executorService = Executors.newFixedThreadPool(10);
    }

    @Override
    public void process(final Map<String, String> bean) {
        if (SnmptrapService.log.isDebugEnabled()) {
            SnmptrapService.log.debug("receive a snmp trap bean {}", bean);
        }
        try {
            this.executorService.execute(new Runnable() {
                @Override
                public void run() {
                    SnmptrapService.this.processTrap(bean);
                }
            });
        } catch (final Exception e) {
            SnmptrapService.log.error(e.getMessage(), e);
        }
    }

    public void processTrap(final Map<String, String> bean) {

        if (SnmptrapService.log.isDebugEnabled()) {
            SnmptrapService.log.debug("process snmp trap in thread {}", bean);
        }

        if (!SnmptrapService.this.setResourceCode(bean)) {
            if (SnmptrapService.log.isWarnEnabled()) {
                SnmptrapService.log.warn("associate relationship is not found in databus: {}", bean);
            }
            return;
        }

        bean.put(SnmptrapServer.alarmContent, bean.get(SnmptrapServer._27) + "@@" + bean.get(SnmptrapServer._28));
        bean.remove(SnmptrapServer._27);
        bean.remove(SnmptrapServer._28);

        this.template.convertAndSend(this.redisSubscribeChannel, JsonUtils.pojoToJson(bean));

    }

    @SuppressWarnings("unchecked")
    public List<Map<String, String>> getAlarms(final String resourceCode) {
        List<Map<String, String>> cachedData = new ArrayList<>();
        if (this.cacheService.isInCache("databus::alarm", resourceCode)) {
            cachedData =
                    (List<Map<String, String>>) this.cacheService.get("databus::alarm",
                            resourceCode);
        }

        return cachedData;
    }

    /**
     * 根据子系统设备编码查询databus资源code
     *
     * @param bean
     * @return
     */
    private boolean setResourceCode(final Map<String, String> bean) {
        final String cacheName = DatabusConstant.CACHE_NAME_ASSOCIATE;
        boolean result = false;
        try {
            final String associate = bean.get(SnmptrapServer._7);
            if (StringUtils.isNotBlank(associate)) {
                final boolean isInCache = this.cacheService.isInCache(cacheName, associate);
                ResourceDTO resource = null;
                if (isInCache) {
                    resource = (ResourceDTO) this.cacheService.get(cacheName, associate);
                } else {
                    final ResultDTO<ResourceDTO> response =
                            SnmptrapService.this.associateResourceService.findResource(associate);
                    if (response.isSuccess() && (null != response.getData())) {
                        resource = response.getData();
                        this.cacheService.put(cacheName, associate, resource);
                    }
                }

                if (null != resource) {
                    bean.put(SnmptrapServer._7, resource.getCode());
                    result = true;
                }
            }
        } catch (final Exception e) {
            SnmptrapService.log.warn("{}", e.getMessage());
        }
        return result;
    }
}
